package com.wuad.platformwuad.module.study.Timer;

import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;

import java.time.LocalDateTime;

/**
 * CRON 表达式
 * @Scheduled注解是Spring Boot提供的用于定时任务控制的注解，主要用于控制任务在某个指定时间执行，或者每隔一段时间执行。
 *
 * @author wuad
 * @date 2023年09月07日 20:07
 */
@Slf4j
public class CronDemo {


    /**
     * CRON周期性任务：如从第一个10秒后，每隔5秒执行
     * 参数顺序：
     * 秒-分-时-日-月-周
     */
    @Scheduled(cron="10/5 * * * * ?")
    public void cronSchedule() {
        log.info(">>>>>>>>Cron schedule:{}", LocalDateTime.now());
    }

    /**
     * 延迟固定时间周期性执行（从服务启动后开始）
     * 服务启动时间：10:30，任务在10:33开始执行，
     * 此后以3秒为周期执行
     */
    @Scheduled(fixedDelay = 3000)
    public void fixedDelaySchedule() {
        log.info(">>>>>>>>FixedDelay schedule:{}", LocalDateTime.now());
    }

    /**
     * 固定周期执行
     * 固定每4秒执行一次
     */
    @Scheduled(fixedRate = 4000)
    public void fixedRateSchedule() {
        log.info(">>>>>>>>FixedRate schedule:{}", LocalDateTime.now());
    }

    /**
     * 首次延迟周期性执行，
     * 服务启动后，延迟2秒执行，
     *
     * 此后，每3秒执行一次
     */
    @Scheduled(initialDelay = 2000, fixedRate = 3000)
    public void initialDelaySchedule() {
        log.info(">>>>>>>>InitialDelay and FixedRate schedule:{}", LocalDateTime.now());
    }

    /**
     * CRON类型的表达式，配置定时任务，共有6个时间粒度，
     * 参数样式：a b c d e f
     * 从左到右分别表示：
     * 秒、分、小时、天、月、星期。
     * 序号	参数	取值范围	特殊字符
     * 1	秒	[0, 59]	* , - /
     * 2	分钟	[0, 59]	* , - /
     * 3	小时	[0, 23]	* , - /
     * 4	日期	[1, 31]	* , - / ? L W
     * 5	月	[1, 12]或[JAN, DEC]	* , - /
     * 6	星期	[1,7]或[MON, SUN]	* , - / ? L #
     * ————————————————
     */

    /**
     * 序号	特殊字符	描述	样例
     * 1	*	所有可能的值	如在分钟的位置配置*，表示每一分钟都生效
     * 2	,	枚举值	    表示对应的数据，如分钟位置配置10,20,30，表示在某点的10分、20分和30分执行
     * 3	-	范围	        间隔值1，左右的数据表示上界和下界，如分钟位置配置：10-20，表示某点10分和20分之间，每1分钟执行
     * 4	/	增量	        左侧数据表示起始值，右侧数据表示增量，分钟位置配置：3/10，表示从第一个间隔3分钟后，每10分钟执行，秒位置：2/10，表示从第一个2秒后开始，每10秒执行
     * 5	?	不指定	    在日期或星期中使用，为避免冲突，将另一个位置配置？
     * 6	L	Last，最后一个	日期位置使用L表示最后一天，星期位置使用L表示最后一个星期的最后一天
     * 7	W	除周末以外的有效工作日	日期位置就近原则，如果5W，5日在为星期六，则在4日执行，如果5日是星期日，则在星期一执行，如果5日在周一~周五，则在5日当天执行
     * 8	#	确定每个月第几个星期几，仅支持星期	星期位置，4#2表示某月的第二个星期四
     * ————————————————
     */

    /**
     * 配置	            描述
     * 0/5 * * * * ?	每5秒执行一次
     * 0 0/2 * * * ?	每两分钟执行一次
     * 0 2 3 1 * ？	每月1日3点2分执行一次
     * 0 2 3 1 1-3 ？	1月到3月的：1日3点2分执行一次
     * 0 0 2,3,4,5 * * ?	每天2点、3点、4点和5点执行一次
     * 0 10 2 * * ?	每天2:10分执行一次
     * 0 0-5 14,16 * * ?	每天14:00到14:55和16:00到16:55每5分钟执行一次
     * 0 10 10 L * ?	每月最后一天的10:10执行一次
     * 0 10 10 5W * ?	每月的工作日5日10:10分执行，如果5日为周六，则往前退一天（星期五），4日10:10执行，如果5日为星期日，则往后推一天（星期一），6日10:10日执行
     * 0 10 10 ？* 4#2	每月的第二个星期四10:10执行一次
     */
}
